package gazzera.swing;

import gazzera.gui.*;
import gazzera.gui.messages.*;
import gazzera.swing.browse.*;
import gazzera.swing.components.*;
import gazzera.swing.components.Box;
import gazzera.swing.download.*;
import gazzera.swing.model.*;
import gazzera.swing.network.*;
import gazzera.swing.shares.*;
import gazzera.swing.utility.*;
import gazzera.utils.*;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

import javax.swing.*;


public class Gazzera extends JFrame implements GuiInterface
{

	public final GuiInterface gui;
	private NetworkList networkList;
	private DownloadList downloadList;
	private ShareList shareList;
	private BrowseTree browseTree;
	private StatusBar statusBar;
	private JTextField gidLabel;
	public JTable browseFileTable;
	
	public String folder = "";

	public Map<String, ChatWindow> chats = new HashMap<String, ChatWindow>();
	public Collection<String> allGroups = new HashSet<String>();
	
	
	public Gazzera(File keystore)
	{
		super("Gazzera");
		//JOptionPane.showMessageDialog(null, "Loading");
		
		setIconImage(new ImageIcon(ResourceLoader.get("icon.png")).getImage());
		
		this.setSize(600, 400);
	    
		final Gazzera t = this;
		this.addWindowListener(new WindowAdapter()
		{
			@Override
			public void windowClosing(WindowEvent e)
			{
				try
				{
				    Set<ChatWindow> c = new HashSet<ChatWindow>(chats.values());
				    for (ChatWindow cw: c)
				    {
					cw.dispose();
				    }
					if (gui != null)
						gui.pass(new Quit());
				}
				catch (Exception e1)
				{
					JOptionPane.showMessageDialog(t, e1.getMessage());
				}
				t.dispose();
			}
		});
		//setJMenuBar(buildMenu());
		add(buildGui());
		setVisible(true);
		
		GuiInterface nonFinal = null;
		try
		{
			setTitle("Starting");
			nonFinal = CoreFactory.createCore(keystore, this);
		}
		catch (Exception e1)
		{
			JOptionPane.showMessageDialog(t, e1.getMessage());
			e1.printStackTrace();
			System.exit(0);
		}
		gui = nonFinal;
		gui.pass(new Status());
		
		//ChatWindow w = new ChatWindow("ciccio", "sghgshdfljashvuhrv3");
		//w.setVisible(true);
	}


	public void log(String s)
	{
		System.out.println("LOG: "+s);
		//txtLog.append(s + "\n");
		//txtLog.setCaretPosition(txtLog.getText().length());
	}
	public void closeChatWindow(ChatWindow w)
	{
		chats.remove(w.hash);
		w.dispose();
	}
	public ChatWindow createChatWindow(String hash)
	{
		ChatWindow w = chats.get(hash);
		Connection c = networkList.getConnection(hash);
		if(w==null)
		{	
			w = new ChatWindow(c.nickname, c.hash, gui, this);
			chats.put(c.hash, w);
			w.setVisible(true);
			w.input.requestFocus();
		}
		return w;
	}
	public void handleGuiMessage(GuiMessage msg)
	{
		 // here we receive message from the core
		if(msg instanceof Intro)
		{
			setTitle("Gazzera");
			gidLabel.setText(((Intro)msg).nickname+"@"+((Intro)msg).ourGid+"@"+((Intro)msg).address+":"+((Intro)msg).port);
			folder = ((Intro)msg).folder;
		}
		else if(msg instanceof Log)
		{
			log(((Log) msg).msg);
			statusBar.setText(((Log) msg).msg);
		}
		else if(msg instanceof ShareInfo)
		{
			ShareInfo s = (ShareInfo)msg;
			shareList.updateShare(s.id, s.folder, s.groups);
		}
		else if(msg instanceof ChatMessage)
		{
			ChatMessage m = (ChatMessage) msg;
			ChatWindow w = createChatWindow(m.hash);
			w.text.append("<"+w.nickname+"> "+m.text+"\n");
		}
		else if (msg instanceof PersonUpdate)
		{
			PersonUpdate p = (PersonUpdate) msg;
			Connection c = new Connection();
			c.hash = p.hash;
			c.host = p.host;
			c.nickname = p.nickname;
			c.onlineStatus = p.onlineStatus;
			c.port = p.port;
			c.status = p.status;
			c.groups = p.groups;
			networkList.updateConnection(c);
			browseTree.updateConnection(c);
		}
		else if (msg instanceof DownloadUpdate)
		{
			DownloadUpdate p = (DownloadUpdate) msg;
			Download c = new Download();
			c.id = p.id;
			c.fileId = p.fileId;
			c.name = p.name;
			c.size = p.size;
			c.downloaded = p.downloaded;
			c.speed = p.speed;
			downloadList.updateDownload(c);
		}
		else if (msg instanceof RemoveDownload)
		{
			RemoveDownload p = (RemoveDownload) msg;
			
			downloadList.removeDownload(p.id);
		}
		else if (msg instanceof GuiBrowseReplyFolder)
		{
			GuiBrowseReplyFolder m = (GuiBrowseReplyFolder) msg;
			browseTree.addFolder(m.userHash, m.parent, m.folder, m.hasSubfolder);
		}
		else if (msg instanceof GuiBrowseReplyFile)
		{
			GuiBrowseReplyFile m = (GuiBrowseReplyFile) msg;
			browseTree.addFile(m.userHash, m.parent, m.fileId, m.name, m.size);
		}
		else if (msg instanceof GuiBrowseReplyFinished)
		{
			GuiBrowseReplyFinished m = (GuiBrowseReplyFinished) msg;
			browseTree.finished(m.userHash, m.parent);
		}
		else if (msg instanceof AllCurrentGroups) {
			allGroups = ((AllCurrentGroups)msg).groups;
		}
	}
	@Override
	public void pass(final GuiMessage msg)
	{
		// i pass the message throu invokeLater to ensure execution in the
		// main swing thread.
		SwingUtilities.invokeLater(new Runnable()
		{
			@Override
			public void run()
			{
				handleGuiMessage(msg);
			}
		});
	}
	public Component buildGui()
	{
		Box panel = new Box(true);
		
		Box gidBox = new Box(false);
		
		gidLabel = new JTextField("Waiting your GID");
		gidLabel.setBorder(null);
		gidLabel.setOpaque(false);
		gidLabel.setEditable(false);

		gidBox.add(new JLabel("<html><b>Your GID: </b></html>"), false);
		gidBox.add(gidLabel, true);
		gidBox.setMinimumSize(new Dimension(200, 20));
		panel.add(gidBox, false);
		
		panel.add(buildNotepad(), true);
		statusBar = new StatusBar();
		statusBar.setText("Initializing...");
		panel.add(statusBar, false);
		
		// panel.setPreferredSize(new Dimension(500,300));
		return panel;
	}


	public JMenuBar buildMenu()
	{
		JMenuBar bar;
		JMenu menu;
		JMenuItem menuItem;

		//Create the menu bar.
		bar = new JMenuBar();

		bar.setBorderPainted(false);
		//bar.setBorder(BorderFactory.createLoweredBevelBorder());
		//Build the first menu.
		menu = new JMenu("File");
		
		
		bar.add(menu);

		//a group of JMenuItems
		menuItem = new JMenuItem("Exit");
		//menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_F4, ActionEvent.ALT_MASK));
		
		menu.add(menuItem);



		
		return bar;
	}
	public Component buildNotepad()
	{
		JPanel panelNetwork = buildNetworkPanel();
	    
	    JComponent panelBrowse = buildBrowsePanel();
	    JPanel panelSearch = new JPanel();
	    JPanel panelDownloads = buildDownloadPanel();
	    JPanel panelUploads = new JPanel();
	    JPanel panelShared = buildSharedPanel();
	    JPanel panelSettings = new JPanel();
	    
	    JTabbedPane tpane = new JTabbedPane();
	    
	    tpane.addTab("Network", new ImageIcon(ResourceLoader.get("network-server.png")), panelNetwork, "Your friend list.");
	    tpane.addTab("Browse", new ImageIcon(ResourceLoader.get("folder.png")), panelBrowse, "Browse shared folders.");
	    tpane.addTab("Search", new ImageIcon(ResourceLoader.get("system-search.png")), panelSearch, "Search for files.");
	    tpane.addTab("Downloads", new ImageIcon(ResourceLoader.get("go-bottom.png")), panelDownloads, "Your downloads.");
	    tpane.addTab("Uploads", new ImageIcon(ResourceLoader.get("go-top.png")), panelUploads, "Files you're uploading.");
	    tpane.addTab("Shared", new ImageIcon(ResourceLoader.get("drive-harddisk.png")), panelShared, "Set your shared folders.");
	    tpane.addTab("Settings", new ImageIcon(ResourceLoader.get("preferences-system.png")), panelSettings, "Change settings.");
	    //tpane.setEnabledAt(1, false);
	    //tpane.setEnabledAt(3,false);
	    return tpane;
	    
	}

	

	private JPanel buildNetworkPanel()
	{
		networkList = new NetworkList(this);
		JToolBar toolBar = new JToolBar();
		JButton button = new JButton("Add Friend",new ImageIcon(ResourceLoader.get("person.png")));
		button.setVerticalTextPosition(0);
		button.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				String s = JOptionPane.showInputDialog("Enter the GID to add:");
				if(s!=null)
				{
					gui.pass(new AddFriend(s));
				}
			}
		});
		toolBar.add(button);
		
		button = new JButton("Connect",new ImageIcon(ResourceLoader.get("network-wireless.png")));
		button.setVerticalTextPosition(0);
		button.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				String s = JOptionPane.showInputDialog("Enter the address to connect to, in the form address:port");
				if(s!=null)
				{
					String[] x = s.split(":");
					gui.pass(new ConnectUrl(x[0], Integer.parseInt(x[1])));
				}
			}
		});
		
        toolBar.add(button);
        toolBar.setFloatable(false);
        toolBar.setRollover(true);


		JScrollPane scrollPane = new JScrollPane(networkList);
		Box b = new Box(true);
		b.add(toolBar, false);
		b.add(scrollPane, true);
		
		
		
		return b;
		
	}

	private JComponent buildBrowsePanel()
	{
		/*
		DefaultMutableTreeNode m = new DefaultMutableTreeNode("Network", true);
		m.add(new DefaultMutableTreeNode("<html>Person<small style=\"color:#d0d0d0\">@d9ad7896ca87cd6ae876cae987c</small></html>"));
		m.add(new DefaultMutableTreeNode("<html>Gianni<small style=\"color:#d0d0d0\">@6ca87cd6ae87d9ad7896cae987c</small></html>"));
		m.add(new DefaultMutableTreeNode("<html>ProvoUnaProvola<small style=\"color:#d0d0d0\">@d9ad7896ca87cd6ae876cae987c</small></html>"));
			
		
		JTree t = new JTree(new BrowseTree());
		
		
		

		t.setShowsRootHandles(true);
		
		t.collapseRow(0);
		*/
	    	browseTree = new BrowseTree(this);
		JScrollPane s = new JScrollPane(browseTree);
		s.setBorder(null);
		browseFileTable = new FileTable(this);
		/*
		TableColumn col0 = browseFileTable.getColumnModel().getColumn(0); 
        col0.setCellRenderer(new FileIconRenderer());
        col0.setMaxWidth(28);
        col0.setMinWidth(28);
        col0.setResizable(false);
        col0.setHeaderValue("");
        */
		JScrollPane s2 = new JScrollPane(browseFileTable);
		s2.setBorder(null);
		JSplitPane p = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, s, s2);
		p.setDividerLocation(100);
		return p;
	}
	
	private JPanel buildDownloadPanel()
	{
		downloadList = new DownloadList(this);
		JToolBar toolBar = new JToolBar();
		JButton button;
		/*button = new JButton("New Download",new ImageIcon(ResourceLoader.get("person.png")));
		button.setVerticalTextPosition(0);
		button.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				String s = JOptionPane.showInputDialog("Enter the file to add (in the form hash:name:size):");
				if(s!=null)
				{
					String[] x = s.split(":");
					gui.pass(new NewDownload(new Hash(x[0]), x[1], Long.parseLong(x[2])));
					
				}
			}
		});
		toolBar.add(button);
		*/
		button = new JButton("Open folder",new ImageIcon(ResourceLoader.get("folder.png")));
		button.setVerticalTextPosition(0);
		button.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				try
				{
					Desktop.getDesktop().open(new File(folder));
				}
				catch (IOException e)
				{

					e.printStackTrace();
				}
			}
		});
		toolBar.add(button);
		
				
        
        toolBar.setFloatable(false);
        toolBar.setRollover(true);


		JScrollPane scrollPane = new JScrollPane(downloadList);
		Box b = new Box(true);
		b.add(toolBar, false);
		b.add(scrollPane, true);
		return b;
		
	}
	private JPanel buildSharedPanel()
	{
		shareList = new ShareList(this);
		JToolBar toolBar = new JToolBar();
		JButton button = new JButton("Add Share",new ImageIcon(ResourceLoader.get("folder.png")));
		button.setVerticalTextPosition(0);
		button.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				AddShareFolderWindow a = new AddShareFolderWindow(Gazzera.this, null);
				a.setVisible(true);
				/*
				JFileChooser fc = new JFileChooser();
				fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

				int returnVal = fc.showDialog(Gazzera.this, "Select folder");
				if(returnVal == JFileChooser.APPROVE_OPTION )
				{
					System.out.println(fc.getSelectedFile());
				}
				*/
				/*
				String s = JOptionPane.showInputDialog("Enter the file to add (in the form hash:name:size):");
				if(s!=null)
				{
					String[] x = s.split(":");
					gui.pass(new NewDownload(new Hash(x[0]), x[1], Long.parseLong(x[2])));
					
				}
				*/
			}
		});
		toolBar.add(button);
		
		button = new JButton("Refresh shares",new ImageIcon(ResourceLoader.get("view-refresh.png")));
		button.setVerticalTextPosition(0);
		button.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				gui.pass(new RefreshShares());
			}
		});
		toolBar.add(button);
		
				
        
        toolBar.setFloatable(false);
        toolBar.setRollover(true);


		JScrollPane scrollPane = new JScrollPane(shareList);
		Box b = new Box(true);
		b.add(toolBar, false);
		b.add(scrollPane, true);
		return b;
		
	}

	
	public static void main(final String[] args)
	{
	    byte[] b =Hash.EMPTY.toByteArray();
	    System.out.println(b);
	    
	    
		ResourceLoader.c = Thread.currentThread().getContextClassLoader();

		SwingUtilities.invokeLater(new Runnable()
		{

			@Override
			public void run()
			{
				try
				{
					UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

					Toolkit.getDefaultToolkit().getSystemEventQueue().push(new DefaultTextMenuQueue());

					Insets insets = copyInsets(UIManager.getInsets("TabbedPane.tabInsets"));
					if (insets != null)
					{
						insets.top += 8;
						UIManager.put("TabbedPane.tabInsets", insets);
					}

					//ConfigWindow w = new ConfigWindow();
					
					//w.setVisible(true);
					
					// JOptionPane.showInputDialog(null, "Please choose a nickname", "Welcome to gazzera!", 0, System.getProperty("user.name"));
					String keystore = "gazzera.keystore";
					if(args.length>0) keystore = args[0];
					new Gazzera(new File(keystore));
				}
				catch (Exception e)
				{
					JOptionPane.showMessageDialog(null, e.getMessage()+" "+Str.getStackTrace(e));
				}
			}
		});

	}
	

	private static Insets copyInsets(Insets insets) {
	      if (insets != null) {
	         return (Insets) insets.clone();
	      } else {
	         return null;
	      }
	   }

	
}
